/* Param update dialog 
-the name of parameters is hierarchical: parts separated by . or a :
	hsearch guides the user in the search of a parameter
	then :
		modify a parameter
		or affectation to a digital trim

# ============================================================================
# Copyright (C) 2008 2009 Robert Spilleboudt
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#============================================================================
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "io.h"
#include "rccl.h"
#include"util/lcd.h"
//declaration of the external data, common to all the RCCL functions
extern struct rccl_data rc; 


int hcount1(int i){//count the numbre of separators (. :) in a param
	i=i+3; //start of string
	int n=0;
	do{
		if (lib_getchar(i)=='.' ||lib_getchar(i)==':')
			n++;
		i++;
	}
	while (lib_getchar(i)!='\0');
	if (lib_getchar(i-1)==':')
		return n-1;//the last : is not a separator
	return n;
}
int hcount0(int i){//count the numbre of separators UNTIL the : (short name)
	i=i+3; //start of string
	int n=0;
	do{
		if (lib_getchar(i)=='.' )
			n++;
		i++;
	}
	while (lib_getchar(i)!='\0' || lib_getchar(i)==':' );
	return n;
}

void hgetText(char *text, int i,int n){//returns the text at index i,from begin to the sepatator n
	// example abc.defg.hzf  n=2 -> abc.defg
	int j=0; //index in the output text
	while( n>0 && j<MAX_PARAM_NAME){
		text[j]=lib_getchar(i);
		i++;
		j++;
		if (lib_getchar(i)=='.' ||lib_getchar(i)==':')
			n--;	
	}
	text[j]=lib_getchar(i); //with the last  . or : included
	text[j+1]='\0';
}
void hgetVarText(char *text,int index){ // returns the name of the parameter  at N_tx[index]
	int i=0;
	//printf("hgetVarText index=%i\n" ,index);
	while(i<MAX_PARAM){
		if(lib_getchar(i)=='6' &&lib_getchar(i+1)==index){
			//strcpy(text,&lib.name[i+3]);
			int j=0;
			i=i+3;
			while (lib_getchar(i)!= '\0'){
				text[j]=lib_getchar(i);
				j++;
				i++;
			}
			text[j]='\0';
			//text =&lib.name[i+3];
			//printf("hgetVarText   =%s\n",text);
			return;
		}
		//i= i+4+ strlen(&lib.name[i+3]);//next parameter
		while (lib_getchar(i)!= '\0')
			i++;
		i++;//next parameter
	}
	text="?";
}

char* htextlcd(char *text){//if the text is too long, align right
	if (strlen(text)<= LCD_DISP_LENGTH)
		return text;
	else{
		int diff;
		diff =  strlen(text)-  LCD_DISP_LENGTH;
		return &text[diff];
	}
}


int hgetFirst(){ //get first parameter (begin of the list)
	int i=0;//index of the lib char array
	int maxloop = 100;
	while(lib_getchar(i)!='6' && maxloop>0){
		//i= i+4+ strlen(&lib.name[i+3]);//next parameter
		i=i+3;
		while (lib_getchar(i)!= '\0')
			i++;
		i++;//next parameter
		maxloop--;
	}
	return i;
}
int hcmp(int p, int c,int n){//compare two parameters
	/*  n=number of selected points
	the proposed param is p and the current is c
	returns 0 if equal (same chars -> nselpt+1
		ail.prof.a == ail.prof.b if nselpt =0 or 1
	returns -1 if current c < p
	returns +1 if c>p	*/
	//printf("hcmp p=%i  c=%i \n",p,c);
	//hprintParam(p);
	//hprintParam(c);
	p+=3;
	c+=3;
	
	while(n>0 &&lib_getchar(p)!='\0'  &&lib_getchar(c)!='\0'){
		if (lib_getchar(c)>lib_getchar(p)){
			//printf("hcmp >  p=%i\n",p);
			return 1;
		}
		if(lib_getchar(c)<lib_getchar(p)) {
			//printf("hcmp <  p=%i\n",p);
			return -1;
		}
		if (lib_getchar(c)=='.' || lib_getchar(c)==':')
			n--;	
		p++;
		c++;
	}
	//printf("hcmp =  p=%i\n",p);
	return 0;
}
int hgetNext(int p){//find next parameter to display
	int i=p;
	int lasti;
	do{
		lasti=i;
		//i= i+4+ strlen(&lib.name[i+3]);//next parameter
		i=i+3;
		while (lib_getchar(i)!= '\0')
			i++;
		i++;//next parameter
		if(lib_getchar(i)!='6' )  //EOF :last one
			return p;
		if (rc.nselpt>0 &&  hcmp(p,i,rc.nselpt)!=0)
			return lasti;
		if( hcmp(p,i,rc.nselpt+1)!=0)
			return i;
	}
	while (i< MAX_PARAM  &&lib_getchar(i)=='6');
	
	return lasti;	
}

int hgetFormer(int p){//go backwards to find next parameter to display
	int i=p;
	int lasti;
	do        {  //find the \0 marker before the string
		lasti=i;
		i=i-2;
		while (lib_getchar(i)!='\0')
			i--;
		i=i-2;
		if(i<0 || (lib_getchar(i)!='6' ))  //EOF :last one
			return p;
		//hprintParam(i);
		if (rc.nselpt>0 &&  hcmp(p,i,rc.nselpt)!=0)
			return lasti;
		if( hcmp(p,i,rc.nselpt+1)!=0)
			return i;
	}		
	while (i>1  &&lib_getchar(i)=='6');
	return lasti;	
}



int hsearch (uint8_t mode){ //main search function, returns the index of the selected variable or 255
	/* called by
		menu_param_tune   init (9) search (2)
		menu_param_dt   (0)
	*/

	//mode2  = search full length of the parameter name, from the last parameter found
	//mode 0 search maximum until :
	//mode 9 reset search to the beginning
	//control data
	// see rccl.h for the format of "lib"
	char text[MAX_PARAM_NAME];
	int menu;
	if(mode==9){
		rc.proposed=0;
		rc.nselpt =0 ;//number of separators in the selected filter
		//printf("hsearch reset mode 9\n");
		return 255;
	}
		
	if(mode <2 || rc.proposed==0){ //initial position = first parameter
		rc.proposed=hgetFirst();
		rc.nselpt =0;
	}
	int n;
	while(1){
		hgetText(text,rc.proposed+3,rc.nselpt+1);
		//printf("hsearch var=%i text=%s rc.nselpt=%i  rc.proposed=%i \n",lib_getchar(rc.proposed+1),text,rc.nselpt,rc.proposed);
		menu=hgetMenuChoice(htextlcd(text)); //this is the rcloop
		if (menu==MENU_DOWN)
			rc.proposed=hgetNext(rc.proposed);
		if (menu==MENU_UP)
			rc.proposed=hgetFormer(rc.proposed);
		if (menu==MENU_SELECT){
			if (mode==1||mode==2)
				n=hcount1(rc.proposed);//count the separators 
			else
				n=hcount0(rc.proposed); //count the separators until the :
			//printf("hsearch select %i n=%i,pt=%i \n",lib_getchar(rc.proposed+1),n,rc.nselpt);
			if (rc.nselpt >= n){//the full lenght is selected
				//printf("hsearch found %i\n",lib_getchar(rc.proposed+1));
				return lib_getchar(rc.proposed+1) ; //the selection is done				
			}
			rc.nselpt++;
		}
		if (menu==MENU_BACK){
			rc.nselpt--;
			if (rc.nselpt<0)
				return 255;//nothing selected
		}		
	}
}
void param_init(){ //initialize the program
	int i;
	for (i=0; i<PARAM_N; i++){
		rc.io_state[i]=0;
		rc.param_button[i]=0;

	}
	for (i=0; i<DTRIM_N; i++){
		rc.io_timer[i]=0;
		rc.pvar[i]=255; 
		rc.vvar[i]=255;
	}	
	rc.nselpt=0;
	rc.proposed=0;
}


void param_button(){//test if a button is pushed to assign a parameter to the digital trim
	int i;
	for (i=0; i< PARAM_N  ;i++){
		if ( io_getButton(i+1) ==1){ // ! +1
			//printf("param_button =%i \n",i);
			char s[MAX_PARAM_NAME]="";
			if (rc.param_button[i]==255)
				return;
				
			rc.pvar[0] = rc.param_button[i];
			lcd_clrscr();
			lcd_puts_p(PSTR("Select \n"));
			hgetVarText(s,rc.vvar[0]); // !ne fonctionne pas pour un pvar
			lcd_puts (s);
			//printf("param_button =%i pvar=%i  vvar=%i =%s\n",i,rc.pvar[0],rc.vvar[0],s);
			rc.lcd_timer=rc.clock_calc;
			io_beep_set(BEEPSTD);
			return;
		}
	}		
}

//*****************phases names***************************************************
void getPhaseName(char *phaseName , int phase, int len){// et the phase name s, for the logical var at index i
	int i=0;//index of the lib char array
	int maxloop = 100;
	if (rc.phase==255){
		strcpy_P (phaseName,PSTR("*")); //no phase
		return;
	}
	while(lib_getchar(i)=='5' && maxloop>0 &&  lib_getchar(i+1) != phase){
		//printf("param code 5 phase=%i\n", lib_getchar(i+1));
		//i= i+4+ strlen(&lib.name[i+3]);//next parameter
		i=i+3;
		while (lib_getchar(i)!= '\0')
			i++;
		i++;//next parameter
		maxloop--;
	}
	if (lib_getchar(i)!='5') { //big error :not found
		strcpy_P (phaseName,PSTR("Error")); //no phase
		return;	
	}
		
		
	// found at i
	//strncpy( phaseName ,&lib.name[i+3],len);
	//printf("param code 5 phase=%i found at %i\n", phase,i);
	int j=0;
	i=i+3;
	while (lib_getchar(i)!= '\0'){
		phaseName[j]=lib_getchar(i);
		j++;
		i++;
	}
	phaseName[j]='\0';
	return;
}
//*****************error messages*********************************************************
void getLCDmessage(char *message, int lineNumber){
	//message max length 16
	int i=0;//index of the lib char array
	while(lib_getchar(i)!='9' ||  lib_getchar(i+1) != lineNumber){
		if (lib_getchar(i)==OP_EOF) { //not found
			strcpy_P (message,PSTR("Error")); 
			return;	
		}
		
		//i= i+4+ strlen(&lib.name[i+3]);//next parameter
		i=i+3;
		while (lib_getchar(i)!= '\0')
			i++;
		i++;//next parameter
	}

	// found at i
	//printf("param code 9 lineNumber=%i found at %i\n", lineNumber,i);
	int j=0;
	i=i+3;
	while (lib_getchar(i)!= '\0' && j<16){
		message[j]=lib_getchar(i);
		j++;
		i++;
	}
	message[j]='\0';
	return;
	
}







